{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TensorFlow.js 部署模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1.0\n",
      "sys.version_info(major=3, minor=7, micro=6, releaselevel='final', serial=0)\n",
      "matplotlib 3.1.3\n",
      "numpy 1.18.1\n",
      "pandas 1.0.1\n",
      "sklearn 0.22.1\n",
      "tensorflow 2.1.0\n",
      "tensorflow_core.python.keras.api._v2.keras 2.2.4-tf\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl,np,pd,sklearn,tf,keras:\n",
    "    print(module.__name__,module.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用cli工具进行模型转化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "usage: TensorFlow.js model converters. [-h]\n",
      "                                       [--input_format {tf_saved_model,tfjs_layers_model,tf_frozen_model,keras,keras_saved_model,tf_hub}]\n",
      "                                       [--output_format {keras_saved_model,tfjs_graph_model,keras,tfjs_layers_model}]\n",
      "                                       [--signature_name SIGNATURE_NAME]\n",
      "                                       [--saved_model_tags SAVED_MODEL_TAGS]\n",
      "                                       [--quantization_bytes {1,2}]\n",
      "                                       [--split_weights_by_layer] [--version]\n",
      "                                       [--skip_op_check]\n",
      "                                       [--strip_debug_ops STRIP_DEBUG_OPS]\n",
      "                                       [--weight_shard_size_bytes WEIGHT_SHARD_SIZE_BYTES]\n",
      "                                       [--output_node_names OUTPUT_NODE_NAMES]\n",
      "                                       [input_path] [output_path]\n",
      "\n",
      "positional arguments:\n",
      "  input_path            Path to the input file or directory. For input format\n",
      "                        \"keras\", an HDF5 (.h5) file is expected. For input\n",
      "                        format \"tensorflow\", a SavedModel directory, frozen\n",
      "                        model file, or TF-Hub module is expected.\n",
      "  output_path           Path for all output artifacts.\n",
      "\n",
      "optional arguments:\n",
      "  -h, --help            show this help message and exit\n",
      "  --input_format {tf_saved_model,tfjs_layers_model,tf_frozen_model,keras,keras_saved_model,tf_hub}\n",
      "                        Input format. For \"keras\", the input path can be one\n",
      "                        of the two following formats: - A topology+weights\n",
      "                        combined HDF5 (e.g., generated with\n",
      "                        `keras.model.save_model()` method). - A weights-only\n",
      "                        HDF5 (e.g., generated with Keras Model's\n",
      "                        `save_weights()` method). For \"keras_saved_model\", the\n",
      "                        input_path must point to a subfolder under the saved\n",
      "                        model folder that is passed as the argument to\n",
      "                        tf.contrib.save_model.save_keras_model(). The\n",
      "                        subfolder is generated automatically by tensorflow\n",
      "                        when saving keras model in the SavedModel format. It\n",
      "                        is usually named as a Unix epoch time (e.g.,\n",
      "                        1542212752). For \"tf\" formats, a SavedModel, frozen\n",
      "                        model, or TF-Hub module is expected.\n",
      "  --output_format {keras_saved_model,tfjs_graph_model,keras,tfjs_layers_model}\n",
      "                        Output format. Default: tfjs_graph_model.\n",
      "  --signature_name SIGNATURE_NAME\n",
      "                        Signature of the SavedModel Graph or TF-Hub module to\n",
      "                        load. Applicable only if input format is \"tf_hub\" or\n",
      "                        \"tf_saved_model\".\n",
      "  --saved_model_tags SAVED_MODEL_TAGS\n",
      "                        Tags of the MetaGraphDef to load, in comma separated\n",
      "                        string format. Defaults to \"serve\". Applicable only if\n",
      "                        input format is \"tf_saved_model\".\n",
      "  --quantization_bytes {1,2}\n",
      "                        How many bytes to optionally quantize/compress the\n",
      "                        weights to. 1- and 2-byte quantizaton is supported.\n",
      "                        The default (unquantized) size is 4 bytes.\n",
      "  --split_weights_by_layer\n",
      "                        Applicable to keras input_format only: Whether the\n",
      "                        weights from different layers are to be stored in\n",
      "                        separate weight groups, corresponding to separate\n",
      "                        binary weight files. Default: False.\n",
      "  --version, -v         Show versions of tensorflowjs and its dependencies\n",
      "  --skip_op_check       Skip op validation for TensorFlow model conversion.\n",
      "  --strip_debug_ops STRIP_DEBUG_OPS\n",
      "                        Strip debug ops (Print, Assert, CheckNumerics) from\n",
      "                        graph.\n",
      "  --weight_shard_size_bytes WEIGHT_SHARD_SIZE_BYTES\n",
      "                        Shard size (in bytes) of the weight files. Currently\n",
      "                        applicable only to output_format=tfjs_layers_model.\n",
      "  --output_node_names OUTPUT_NODE_NAMES\n",
      "                        The names of the output nodes, separated by commas.\n",
      "                        E.g., \"logits,activations\". Applicable only if input\n",
      "                        format is \"tf_frozen_model\".\n"
     ]
    }
   ],
   "source": [
    "!tensorflowjs_converter --help"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# keras_to_tfjs_layers(推荐)\n",
    "!tensorflowjs_converter --input_format keras --output_format tfjs_layers_model \\\n",
    "    ./graph_def_and_weights/fashion_mnist_model.h5 ./tfjs_models/keras_to_tfjs_layers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# keras_to_tfjs_graph\n",
    "!tensorflowjs_converter --input_format keras --output_format tfjs_graph_model \\\n",
    "    ./graph_def_and_weights/fashion_mnist_model.h5 ./tfjs_models/keras_to_tfjs_graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# saved_model_to_tfjs_graph\n",
    "!tensorflowjs_converter --input_format tf_saved_model --output_format tfjs_graph_model \\\n",
    "    ./keras_saved_graph/ ./tfjs_models/saved_model_to_tfjs_graph"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用程序将py模型转为tfjs模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "f:\\condaenv\\tflatest\\lib\\site-packages\\tensorflowjs\\converters\\keras_h5_conversion.py:122: H5pyDeprecationWarning: The default file mode will change to 'r' (read-only) in h5py 3.0. To suppress this warning, pass the mode you need to h5py.File(), or set the global default h5.get_config().default_file_mode, or set the environment variable H5PY_DEFAULT_READONLY=1. Available modes are: 'r', 'r+', 'w', 'w-'/'x', 'a'. See the docs for details.\n",
      "  return h5py.File(h5file)\n"
     ]
    }
   ],
   "source": [
    "loaded_keras_model = keras.models.load_model(\n",
    "    './graph_def_and_weights/fashion_mnist_model.h5')\n",
    "\n",
    "import tensorflowjs as tfjs\n",
    "tfjs.converters.save_keras_model(loaded_keras_model, './tfjs_models/keras_to_tfjs_layers_py')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
